cmake_minimum_required(VERSION 3.6)

project(azurestoragelite)
set(CMAKE_CXX_STANDARD 11)

option(BUILD_TESTS       "Build test codes"                  OFF)
option(BUILD_SAMPLES     "Build sample codes"                OFF)
option(BUILD_SHARED_LIBS "Request build of shared libraries" OFF)
option(BUILD_ADLS        "Build ADLS Gen2 codes"             OFF)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

set(AZURE_STORAGE_LITE_HEADER
  include/storage_EXPORTS.h

  include/logging.h
  include/base64.h
  include/common.h
  include/compare.h
  include/constants.h
  include/constants.dat
  include/executor.h
  include/hash.h
  include/retry.h
  include/utility.h
  include/mstream.h

  include/tinyxml2.h
  include/xml_parser_base.h
  include/tinyxml2_parser.h
  include/xml_writer.h

  include/json_parser_base.h

  include/storage_account.h
  include/storage_credential.h
  include/storage_outcome.h
  include/storage_stream.h
  include/storage_url.h
  include/storage_errno.h

  include/storage_request_base.h
  include/get_blob_request_base.h
  include/put_blob_request_base.h
  include/delete_blob_request_base.h
  include/copy_blob_request_base.h
  include/create_container_request_base.h
  include/delete_container_request_base.h
  include/set_container_metadata_request_base.h
  include/list_containers_request_base.h
  include/list_blobs_request_base.h
  include/get_block_list_request_base.h
  include/put_block_request_base.h
  include/get_blob_property_request_base.h
  include/set_blob_metadata_request_base.h
  include/get_container_property_request_base.h
  include/put_block_list_request_base.h
  include/append_block_request_base.h
  include/put_page_request_base.h
  include/get_page_ranges_request_base.h

  include/http_base.h
  include/http/libcurl_http_client.h

  include/blob/blob_client.h
  include/blob/download_blob_request.h
  include/blob/create_block_blob_request.h
  include/blob/delete_blob_request.h
  include/blob/copy_blob_request.h
  include/blob/create_container_request.h
  include/blob/delete_container_request.h
  include/blob/set_container_metadata_request.h
  include/blob/list_containers_request.h
  include/blob/list_blobs_request.h
  include/blob/get_blob_property_request.h
  include/blob/set_blob_metadata_request.h
  include/blob/get_container_property_request.h
  include/blob/get_block_list_request.h
  include/blob/put_block_request.h
  include/blob/put_block_list_request.h
  include/blob/append_block_request.h
  include/blob/put_page_request.h
  include/blob/get_page_ranges_request.h
)

set(AZURE_STORAGE_LITE_SOURCE
  src/logging.cpp
  src/base64.cpp
  src/constants.cpp
  src/hash.cpp
  src/utility.cpp

  src/tinyxml2.cpp
  src/tinyxml2_parser.cpp

  src/storage_account.cpp
  src/storage_credential.cpp
  src/storage_url.cpp

  src/get_blob_request_base.cpp
  src/put_blob_request_base.cpp
  src/delete_blob_request_base.cpp
  src/copy_blob_request_base.cpp
  src/create_container_request_base.cpp
  src/delete_container_request_base.cpp
  src/set_container_metadata_request_base.cpp
  src/list_containers_request_base.cpp
  src/list_blobs_request_base.cpp
  src/get_blob_property_request_base.cpp
  src/set_blob_metadata_request_base.cpp
  src/get_block_list_request_base.cpp
  src/get_container_property_request_base.cpp
  src/put_block_request_base.cpp
  src/put_block_list_request_base.cpp
  src/append_block_request_base.cpp
  src/put_page_request_base.cpp
  src/get_page_ranges_request_base.cpp

  src/http/libcurl_http_client.cpp

  src/blob/blob_client.cpp
  src/blob/blob_client_wrapper.cpp
)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

add_library(azure-storage-lite ${AZURE_STORAGE_LITE_HEADER} ${AZURE_STORAGE_LITE_SOURCE})

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
find_package(CURL REQUIRED)
if (UNIX)
  option(USE_OPENSSL "Use OpenSSL instead of GnuTLS" ON)
  if(USE_OPENSSL)
    target_compile_definitions(azure-storage-lite PRIVATE -DUSE_OPENSSL)
    set(OPENSSL_ROOT_DIR ${OPENSSL_ROOT_DIR} /usr/local/opt/openssl)
    find_package(OpenSSL REQUIRED)
    list(APPEND EXTRA_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
  else()
    find_package(GnuTLS REQUIRED)
    list(APPEND EXTRA_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR})
    list(APPEND EXTRA_LIBRARIES ${GNUTLS_LIBRARIES})
  endif()

  if(NOT APPLE)
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(uuid REQUIRED IMPORTED_TARGET uuid)
    list(APPEND EXTRA_LIBRARIES PkgConfig::uuid)
  endif()
elseif(WIN32)
  list(APPEND EXTRA_LIBRARIES rpcrt4 bcrypt)
  target_compile_definitions(azure-storage-lite PRIVATE azure_storage_lite_EXPORTS NOMINMAX)
endif()

if(BUILD_TESTS)
  find_package(Catch2)
  if(NOT Catch2_FOUND)
    find_path(SINGLE_HEADER_CATCH2_INCLUDE_DIR catch2/catch.hpp PATHS ${CATCH2_INCLUDE_DIR})
    message("Found single-header Catch2: ${SINGLE_HEADER_CATCH2_INCLUDE_DIR}/catch2/catch.hpp")
    add_library(Catch2::Catch2 INTERFACE IMPORTED)
    set_target_properties(Catch2::Catch2 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${SINGLE_HEADER_CATCH2_INCLUDE_DIR})
  endif()
endif()

target_include_directories(azure-storage-lite PUBLIC ${PROJECT_SOURCE_DIR}/include ${CURL_INCLUDE_DIRS} PRIVATE ${EXTRA_INCLUDE_DIRS})
target_link_libraries(azure-storage-lite Threads::Threads ${CURL_LIBRARIES} ${EXTRA_LIBRARIES})

if(MSVC)
  target_compile_options(azure-storage-lite PRIVATE /W4 /WX /MP)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  target_compile_options(azure-storage-lite PRIVATE -Wall -Wextra -Werror -pedantic)
endif()

if(BUILD_ADLS)
  add_subdirectory(adls)
endif()

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTS)
  add_subdirectory(test)
endif()

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_SAMPLES)
  add_subdirectory(sample)
endif()

# Set version numbers centralized
set(AZURE_STORAGE_LITE_VERSION_MAJOR 0)
set(AZURE_STORAGE_LITE_VERSION_MINOR 3)
set(AZURE_STORAGE_LITE_VERSION_REVISION 0)

install(DIRECTORY include/ DESTINATION include)
install(TARGETS azure-storage-lite
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    RUNTIME DESTINATION bin)
